from utils.ApiCryptoUtils import api_crypto_utils
from web_server_function.ServerUtils import server_utils, CaptchaError
from utils.ReadUtil import read_util
from utils.log_util import logger
from web_server_function.UserServer import user_server
import time


class UserClient:

    def __init__(self, platform_name, appV):
        # 设备号
        self.deviceid = server_utils.generate_random_string(rando_name="", length=32)
        # 当前时间戳毫秒
        self.ctime = int(time.time() * 1000)
        # 登录用户uid
        self.app_uid = None
        # 登录用户token
        self.token = None
        # app版本号
        self.build = "1.1.9"
        # app系统 ANDRIOD/IOS
        self.platform_name = platform_name
        # app包 BOOKS/XKB
        self.appV = appV

    def user_login(self, login_name, login_password):
        """
        用户手机号、密码登录
        """
        try:
            # 先调用添加短信白名单接口，去掉验证码
            logger.info("------超管登录后台------")
            server_utils.login_background(read_util.read_data()['后台账号密码']['超管账号'],
                                          read_util.read_data()['后台账号密码']['超管密码'])
            logger.info("------超管添加测试账号到短信白名单中------")
            user_server.addSmsWhiteList(login_name)

            logger.info("------用户手机号密码登录------")
            data_dict = {"loginName": login_name, "appUUId": "", "loginType": "UPL", "loginPassword": login_password,
                         "deviceId": self.deviceid, "build": self.build, "token": "",
                         "platformName": self.platform_name, "appV": self.appV, "platform": "2"}
            response = api_crypto_utils.app_post_request(url="/v2/books/userinfo/loginByAccountAndPwd",
                                                         data=data_dict)
            if response['appData']['needGraphicVerificationCode'] == 1:
                logger.info("------获取图文验证码解锁------")
                # 验证解锁手机号获取验证码
                self.checkGraphicVerificationCode(login_name)
                # 解锁成功再次登录
                logger.info("------再次尝试用户登录流程------")
                return self.user_login(login_name, login_password)
            # 获取当前登录用户的token
            self.token = response['appData']['userInfo']['token']
            read_util.update_data('app_token', self.token)
            # 获取当前登录用户的uid
            self.app_uid = response['appData']['userInfo']['rsNo']
            read_util.update_data('app_uid', self.app_uid)
            return response
        except Exception as e:
            server_utils.handle_exception(e, f"用户手机号{login_name}登录失败")

    def sendSmsCode_app(self, login_name):
        """
        手机号注册获取验证码
        """
        try:
            data_dict = {"loginName": login_name, "appUUId": "",
                         "deviceId": self.deviceid,
                         "build": self.build, "token": "", "platformName": self.platform_name, "appV": self.appV}
            code_response = api_crypto_utils.app_post_request(url="/v2/userinfo/register/sendSmsCode", data=data_dict)

            # 调用获取验证码，如果状态为1就进入解锁流程
            if code_response['appData']['needGraphicVerificationCode'] == 1:
                # 验证解锁手机号获取验证码
                self.checkGraphicVerificationCode(login_name)
                # 解锁成功再次手机获取验证码
                return self.sendSmsCode_app(login_name)
            else:
                # 获取后台短信验证码
                server_utils.login_background(read_util.read_data()['后台账号密码']['超管账号'],
                                              read_util.read_data()['后台账号密码']['超管密码'])
                return user_server.userSmsInfo(login_name)
        except Exception as e:
            server_utils.handle_exception(e, f"手机号{login_name}获取验证码失败")

    def app_getCaptcha(self):
        """
        获取图文验证码-验证码发送太多，手机号被锁时使用
        """
        try:
            data_dict = {"appUUId": "", "deviceId": self.deviceid, "build": self.build,
                         "c": self.ctime, "token": "", "platformName": self.platform_name,
                         "t": server_utils.generate_random_string(rando_name="", length=6), "appV": self.appV}

            return api_crypto_utils.app_post_request(url="/captcha", data=data_dict)
        except Exception as e:
            server_utils.handle_exception(e, f"获取图文验证码失败")

    def checkGraphicVerificationCode(self, login_name, scene="register"):
        """
        图文验证码验证解锁
        """
        # 获取图形验证码照片
        try:
            captcha_response = self.app_getCaptcha()
            # 识别获取验证码
            code = server_utils.getAppImgCode(captcha_response['appData']['captchaBase64'])

            data_dict = {"loginName": login_name, "appUUId": "", "deviceId": self.deviceid,
                         "triggerType": "1", "build": self.build, "captcha": code, "c": self.ctime,
                         "token": "", "platformName": self.platform_name, "appV": self.appV}

            api_crypto_utils.app_post_request(url=f"/v2/userinfo/{scene}/checkGraphicVerificationCode",
                                              data=data_dict)
        except Exception as e:
            server_utils.handle_exception(e, f"图文验证码解锁失败")

    def register_app(self, login_name, login_password):
        """
        校验短信验证码，并设置密码完成注册
        """
        try:
            # 获取手机验证码
            logger.info("------获取手机验证码------")
            code = self.sendSmsCode_app(login_name)

            logger.info("------校验手机验证码------")
            data_dict = {"loginName": login_name, "appUUId": "", "loginPassword": login_password,
                         "deviceId": self.deviceid, "build": self.build, "token": "",
                         "platformName": self.platform_name, "vildatorCode": code, "appV": self.appV}
            response = api_crypto_utils.app_post_request(url="/v2/books/userinfo/register/checkSmsCode", data=data_dict)
            if response['appData']['msg'] == "注册成功":
                # 　获取新注册用户的token
                self.token = response['appData']['userInfo']['token']
                read_util.update_data('app_token', self.token)
                # 获取当前登录用户的uid
                self.app_uid = response['appData']['userInfo']['rsNo']
                read_util.update_data('app_uid', self.app_uid)

                return response
        except Exception as e:
            server_utils.handle_exception(e, f"手机号{login_name}注册失败")

    def cancelSendsmsCode(self, login_name):
        """
        注销用户，发送短信验证码
        """
        try:
            data_dict = {"appUUId": self.app_uid,
                         "ipAddress": "192.168.1.148", "deviceId": self.deviceid,
                         "token": self.token,
                         "platformName": self.platform_name, "mobilePhone": login_name, "t": self.ctime,
                         "appV": self.appV,
                         "build": self.build, "smssigncode": "43092580fpjlkasndlasnldasjdaksldh3l2323", "smsType": "7",
                         "platform": "2", "signs": "38F7C73E6CF4EFA27C6DFC5A9874BACD"}
            response = api_crypto_utils.app_post_request(url="/v2/userinfo/cancelUserInfo/sendSmsCode", data=data_dict)
            # 调用获取验证码，如果状态为1就进入解锁流程
            if response['appData']['needGraphicVerificationCode'] == 1:
                # 验证解锁手机号获取验证码
                self.checkGraphicVerificationCode(login_name, scene="cancelUserInfo")
                # 解锁后重新再发送次验证码
                self.cancelSendsmsCode(login_name)
            else:
                return response
        except Exception as e:
            server_utils.handle_exception(e, f"手机号{login_name}注销发送验证码失败")

    def userAccountCancel(self):
        """
        注销用户账号
        """
        try:
            data_dict = {"appUUId": self.app_uid,
                         "isAgreeCancelAgreement": "2", "deviceId": self.deviceid, "build": self.build,
                         "status": "3",
                         "token": self.token,
                         "platformName": self.platform_name, "appV": self.appV}

            response = api_crypto_utils.app_post_request(url="/v1/userInfo/cancellation", data=data_dict)
            return response
        except Exception as e:
            server_utils.handle_exception(e, f"注销用户账号失败{self.app_uid}")


userClient = UserClient(platform_name="ANDRIOD", appV="BOOKS")

if __name__ == "__main__":
    # 注册流程
    logger.info("注册流程测试开始")
    userClient.register_app("13500000020", "Xkb87654312")
    logger.info("注册流程测试结束\n")
    #
    # # 注销用户
    # logger.info("注销用户测试开始")
    # userClient.userAccountCancel()
    # logger.info("注销用户测试结束\n")

    # 登录流程
    logger.info("登录测试开始")
    userClient.user_login("13500000020", "Xkb87654312")
    logger.info("登录测试结束\n")

    # 注销用户
    logger.info("注销用户测试开始")
    userClient.userAccountCancel()
    logger.info("注销用户测试结束\n")
